/**
 * 
 */
package spl.army.ut;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import spl.army.ItemRequired;
import spl.army.Mission;
import spl.army.Sergeant;
import spl.army.Warehouse;

/**
 * @author Ruby
 *
 */
public class SergeantTest {

	private Sergeant sergeant;
	private final String name = "Moshe";
	private final int maxMissions = 2;
	private final ArrayList<String> skills = new ArrayList<String>(
			Arrays.asList(
						"Sniper",
						"Hacker"
					)
			);
	private final int maxHours = 5;
	private final String priorityOrder = "shortestMission";
	private final int numOfThreads = 5;
	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		this.sergeant = new Sergeant(
						this.name,
						this.maxMissions,
						this.skills,
						this.maxHours,
						this.priorityOrder,
						this.numOfThreads);
	}

	/**
	 * @throws java.lang.Exception
	 */
	@After
	public void tearDown() throws Exception {
	}

	/**
	 * Test method for {@link spl.army.Sergeant#giveMission(spl.army.Mission)}.
	 * @throws InterruptedException 
	 */
	@Test(timeout=500)
	public void testGiveManyMissions() throws InterruptedException {
		ArrayList<ItemRequired> itemsReq = new ArrayList<ItemRequired>();
		ArrayList<Mission> preReqMissions = new ArrayList<Mission>();
		Mission mission = new Mission("dummy", "Hacker" , 1, itemsReq , preReqMissions);
		for(int i=1;i<=this.numOfThreads;i++){
			this.sergeant.giveMission(mission);
			assertTrue(this.sergeant.getActiveMissionsCount() == i);
		}
		
	}
	

	/**
	 * Test method for {@link spl.army.Sergeant#giveMission(spl.army.Mission)}.
	 * @throws InterruptedException 
	 */
	@Test(timeout=1500)
	public void testGiveMission() throws InterruptedException {
		assertTrue(this.sergeant.getAllAssignedMissions().size() == 0);
		ArrayList<ItemRequired> itemsReq = new ArrayList<ItemRequired>();
		String itemName = "AXE";
		itemsReq.add(new ItemRequired(itemName, 3));
		Warehouse.resetWarehouse();
		Warehouse.addItem(itemName, 5);
		ArrayList<Mission> preReqMissions = new ArrayList<Mission>();
		Mission mission = new Mission("dummy", "Hacker" , 1, itemsReq , preReqMissions);
		this.sergeant.giveMission(mission);
		assertTrue(this.sergeant.getActiveMissionsCount() == 1);
		Thread.sleep(50);
		assertTrue(Warehouse.getItemCurrentAmount(itemName) == 2);
		assertTrue(this.sergeant.getAllAssignedMissions().size() == 1);
		assertEquals(this.sergeant.getMissionsLeft(), this.maxMissions-1);
		Thread.sleep(500);
		assertTrue(this.sergeant.getActiveMissionsCount() == 1);
		Thread.sleep(600);
		assertTrue(this.sergeant.getActiveMissionsCount() == 0);
		assertTrue(Warehouse.getItemCurrentAmount(itemName) == 5);
		Warehouse.resetWarehouse();
	}

	/**
	 * Test method for {@link spl.army.Sergeant#getMissionsCount()}.
	 */
	@Test(timeout=100)
	public void testGetMissionsLeft() {
		assertEquals(this.maxMissions, this.sergeant.getMissionsLeft());
		ArrayList<ItemRequired> itemsReq = new ArrayList<ItemRequired>();
		ArrayList<Mission> preReqMissions = new ArrayList<Mission>();
		Mission mission = new Mission("dummy", "Hacker" , 100, itemsReq , preReqMissions);
		this.sergeant.giveMission(mission);
		assertEquals(this.maxMissions - 1, this.sergeant.getMissionsLeft());
	}

	/**
	 * Test method for {@link spl.army.Sergeant#getMissionsLeft()}.
	 */
	@Test
	public void testGetMaxMissions() {
		assertEquals(this.maxMissions, this.sergeant.getMissionsLeft());
	}

	/**
	 * Test method for {@link spl.army.Sergeant#getSkills()}.
	 */
	@Test
	public void testGetSkills() {
		List<String> currentSkills = this.sergeant.getSkills();
		Iterator<String> it = this.skills.iterator();
		String currentSkill;
		while(it.hasNext())
		{
			currentSkill = it.next();
			assertTrue(currentSkills.indexOf(currentSkill) != -1);
		}
		it = currentSkills.iterator();
		while(it.hasNext())
		{
			currentSkill = it.next();
			assertTrue(this.skills.indexOf(currentSkill) != -1);
		}		
	}

	/**
	 * Test method for {@link spl.army.Sergeant#getMaxWorkHours()}.
	 */
	@Test
	public void testGetMaxWorkHours() {
		assertEquals(this.maxHours, this.sergeant.getMaxWorkHours());
	}

	/**
	 * Test method for {@link spl.army.Sergeant#getPriorityOrder()}.
	 */
	@Test
	public void testGetPriorityOrder() {
		assertEquals(this.priorityOrder, this.sergeant.getPriorityOrder());
	}

	/**
	 * Test method for {@link spl.army.Sergeant#getName()}.
	 */
	@Test
	public void testGetName() {
		assertEquals(this.name, this.sergeant.getName());
	}

}
